#!/usr/bin/perl -wc

package RFCMail::Invite::Message;

use strict;
use RFCMail::Util::PackIt::Translator;
use RFCMail::Util::PackIt::Data;

our $STRUCTURE =
    [
     {
	 var8 => ['RFCMail::Util::PackIt::Convert::put_var8', 'RFCMail::Util::PackIt::Convert::get_var8'],
	 domain => ['RFCMail::Util::PackIt::Convert::put_domain', 'RFCMail::Util::PackIt::Convert::get_domain'],
	 u8 => ['RFCMail::Util::PackIt::Convert::put_u8', 'RFCMail::Util::PackIt::Convert::get_u8'],
	 u32 => ['RFCMail::Util::PackIt::Convert::put_u32', 'RFCMail::Util::PackIt::Convert::get_u32'],
	 hex64 => ['RFCMail::Util::PackIt::Convert::put_hex', sub { $_[0]->RFCMail::Util::PackIt::Convert::get_hex(8) }],
	 var => ['write', 'rest'],
	 null => [sub {}, sub { return ("") }],
	 otp_seed => ['RFCMail::Invite::Message::Convert::put_otp_seed', 'RFCMail::Invite::Message::Convert::get_otp_seed'],
     },
     [
      [ 'client_message_id', 'u32' ],
      [ 'message_type_tag', 'u8' ],
      ],
     'message_type_tag',
     {
	 invitation =>
	     [ 1,
	       [
		[ 'service_name', 'var8' ],
		[ 'target_domain', 'domain' ],
		[ 'inviting_domain', 'domain' ],
		],
	       {
		   invitation_expiry => [ 1, 'u8', 1 ],
		   available_hash_scheme => [ 2, 'var', undef ],
		   server_cookie => [ 3, 'var', 1 ],
	       },
	       ],
	 invitation_declined =>
	     [ 2,
	       [],
	       {
		   domain_validation_failed => [ 1, 'null', 1 ],
		   incompatible_timing => [ 2, 'u8', 1 ],
		   additional_information => [ 3, 'var', undef ],
	       },
	       ],
	 address_repudiated =>
	     [ 3,
	       [],
	       {
	       },
	       ],
	 temporary_hold =>
	     [ 4,
	       [
		[ 'hold_time', 'u8' ],
		],
	       {
	       },
	       ],
	 cookie_required =>
	     [ 5,
	       [
		[ 'server_cookie', 'var8' ],
		],
	       {
	       },
	       ],
	 invitation_accepted_otp =>
	     [ 6,
	       [
		[ 'confirmation_window_size', 'u8' ],
		[ 'otp_hash_value', 'hex64' ],
		],
	       {
		   otp_hash_scheme => [ 1, 'var', 1 ],
		   otp_seed_value => [ 2, 'otp_seed', 1 ],
		   server_cookie => [ 3, 'var', 1 ],
	       },
	       ],
	 ready_for_session =>
	     [ 7,
	       [
		[ 'service_name', 'var8' ],
		[ 'target_domain', 'domain' ],
		[ 'inviting_domain', 'domain' ],
		],
	       {
		   authentication_identity => [ 1, 'var', 1 ],
		   server_cookie => [ 2, 'var', 1 ],
	       },
	       ],
	 ready_acknowledged_pos =>
	     [ 8,
	       [
		[ 'call_back_window', 'u8' ],
		],
	       {
	       },
	       ],
	 ready_acknowledged_neg =>
	     [ 9,
	       [],
	       {
		   not_authorised => [ 1, 'null', 1 ],
	       },
	       ],
     }
     ];


sub new {
    my ($class) = @_;
    our $STRUCTURE;
    my $self = RFCMail::Util::PackIt::Translator->new($STRUCTURE);
    return (bless \$self, $class);
}


sub decode {
    my ($self, $packet, $hashref) = @_;
    my $trans = $$self;
    my $data = RFCMail::Util::PackIt::Data->new($packet);
    return ($trans->decode($data, $hashref));
}


sub encode {
    my ($self, $hashref) = @_;
    my $trans = $$self;
    my $data = RFCMail::Util::PackIt::Data->new();
    $trans->encode($hashref, $data);
    return ($data->data());
}



package RFCMail::Invite::Message::Convert;

use strict;


sub put_otp_seed {
    my $self = shift;
    for (@_) {
	die "otp seed not 1-16 alphanumeric chars"
	    if not /^[[:alnum:]]{1,16}$/;
	RFCMail::Util::PackIt::Convert::put_var8($self, $_);
    }
    return ($self);
}


sub get_otp_seed {
    my @seeds = RFCMail::Util::PackIt::Convert::get_var8(@_);
    for (@seeds) {
	die "otp seed not 1-16 alphanumeric chars"
	    if not /^[[:alnum:]]{1,16}$/;
    }
    return (wantarray ? @seeds : $seeds[0]);
}

1;
